package com.vdongchina.thread.executor;


import java.util.concurrent.*;

/**
 * futureTask的简单使用
 * <p>
 * future与callable , futuretask一般都是配合executorservice来使用
 * <p>
 * 注意 future 与 futureTask的区别
 */
public class FutureTaskTest {


    public static void main(String[] args) throws ExecutionException, InterruptedException {

        futureTest(); //future的例子

        futureTaskTest(true); //futureTask的例子

        //String firstOne = executionTask("first one");  //
        //System.out.println(firstOne);


    }


    private static final ConcurrentMap<Object, Future<String>> taskCache = new ConcurrentHashMap<>();

    public static String executionTask(final String taskName) throws ExecutionException, InterruptedException {

        while (true) {

            Future<String> future = taskCache.get(taskName);
            if (future == null) {
                Callable<String> task = new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        return taskName;
                    }
                };

                java.util.concurrent.FutureTask<String> futureTask = new java.util.concurrent.FutureTask<>(task);
                future = taskCache.putIfAbsent(taskName, futureTask);
                if (future == null) {
                    future = futureTask;
                    futureTask.run();
                }

            }
            try {
                return future.get();
            } catch (CancellationException e) {
                taskCache.remove(taskName, future);
            }
        }


    }


    private static void futureTaskTest(Boolean method) throws ExecutionException, InterruptedException {

        FutureTask<String> futureTask = new FutureTask<>(new futureCallable());
        if (method) {
            //第一种执行方式, 通过futureTask的runnable接口来用Thread 线程执行
            Thread thread = new Thread(futureTask);
            thread.start();
        } else {
            //第二种执行方式,通过futureTask的future接口来用executorService 执行
            ExecutorService executorService = Executors.newCachedThreadPool();
            Future<String> submit = (Future<String>) executorService.submit(futureTask);
            System.out.println(submit.get());
        }

    }
    public static String futureTest() throws ExecutionException, InterruptedException {
        futureCallable futureCallable = new futureCallable();
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future future = executorService.submit(futureCallable);
        System.out.println(future.get());
        return null;

    }



    public static class futureCallable implements Callable {
        @Override
        public Object call() throws Exception {
            return "future的返回值! 必须是实现callable接口";
        }
    }


}
